(import
 (except (rnrs base)
         let-values
         map
         error
         vector-map)
 (only (guile)
       lambda* λ
       simple-format)

 ;; standard library
 (ice-9 pretty-print)

 ;; custom modules
 (fileio)
 (pipeline)
 (debug)
 (list-helpers)

  ;; let-values
 (srfi srfi-11)
 ;; hash tables
 (srfi srfi-69)

 ;; graph algos
 (dijkstra)

 (graph-model)
 (graph-reader)
 (graph-utils)
 )


(define input-filename "example-graphs/graph-02.txt")

(define-values (nodes distances-table nodes-table)
  (read-graph input-filename))


(define get-neighbors
  (λ (node)
    "A function, that maps from an actual node struct to a
list of node structures."
    (map (λ (node-name)
           (hash-table-ref nodes-table node-name))
         (node-neighbors node))))


(define get-neighbor-distance
  (λ (node1 node2)
    "A function that returns the distance from NODE1 to NODE2."
    (let ([key (cons (node-name node1) (node-name node2))])
      (hash-table-ref distances-table key))))


(define node<
  (λ (node1 node2)
    "A function introduction an order to nodes. Important for
functional sets implementation backed by a tree
implementation."
    (or (< (node-y node1)
           (node-y node2))
        (and (= (node-y node1)
                (node-y node2))
             (< (node-x node1)
                (node-x node2))))))


(let ([start-node (hash-table-ref nodes-table "A")])
  (let-values ([(distances° routes°)
                (dijkstra-shortest-path start-node
                                        nodes
                                        get-neighbors
                                        get-neighbor-distance
                                        node<
                                        #:distance< <)])
    (simple-format #t "shortest distances from A to other nodes:\n")
    (pretty-print (hash-table->alist distances°))
    (simple-format #t "shortest path from A to T:\n")
    (pretty-print (routes->path routes° (hash-table-ref nodes-table "T")))))
